﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Lenovo.CFI.Common;
using Lenovo.CFI.BLL.DicMgr;
using Lenovo.CFI.Common.Dic;
using Lenovo.CFI.BLL.Sys;
using Lenovo.CFI.Common.Sys;

namespace Lenovo.CFI.BLL
{
    public class StatBl
    {

        public Dictionary<string, int[]> TypeNumberByTopic(int topicID)
        {
            List<Idea> ideas = new IdeaBl().SearchIdeaForStat(topicID, null, null);

            Dictionary<string, int[]> typesNumbers = new Dictionary<string, int[]>();
            foreach (IdeaType type in IdeaTypeDicMgr.Get())
            {
                typesNumbers.Add(type.Code, new int[9]);
            }
            typesNumbers.Add("all", new int[9]);
            foreach (Idea idea in ideas)
            {
                switch (idea.FinalAction)
                {
                    case NextAction.PRODUCT:
                        typesNumbers[idea.FinalType][1]++;
                        typesNumbers["all"][1]++;
                        break;
                    case NextAction.JUSTDOIT: 
                        typesNumbers[idea.FinalType][2]++;
                        typesNumbers["all"][2]++;
                        break;
                    case NextAction.CPROJECT:
                        typesNumbers[idea.FinalType][3]++;
                        typesNumbers["all"][3]++;
                        break;
                    case NextAction.GROUPC:
                        typesNumbers[idea.FinalType][4]++;
                        typesNumbers["all"][4]++;
                        break;
                    case NextAction.TBD:
                        typesNumbers[idea.FinalType][5]++;
                        typesNumbers["all"][5]++;
                        break;
                    case NextAction.MKT:
                        typesNumbers[idea.FinalType][6]++;
                        typesNumbers["all"][6]++;
                        break;
                    case NextAction.NEXTROUND:
                        typesNumbers[idea.FinalType][7]++;
                        typesNumbers["all"][7]++;
                        break;
                    case NextAction.OTHERBU:
                        typesNumbers[idea.FinalType][8]++;
                        typesNumbers["all"][8]++;
                        break;
                }

                typesNumbers[idea.FinalType][0]++;
                typesNumbers["all"][0]++;
            }


            return typesNumbers;
        }

        public Dictionary<int, object[]> TypeNumberByTime(DateTime from, DateTime to)
        {
            List<Idea> ideas = new IdeaBl().SearchIdeaForStat(null, from, to);

            Dictionary<int, object[]> monthNumbers = new Dictionary<int, object[]>();
            for (int i = from.Month; i <= to.Month; i++)
            {
                monthNumbers.Add(i, new object[] {null, 0,0,0,0,0,0,0,0,0,0,0,0});
            }

            List<Topic> topics = new TopicBl().GetTopic().FindAll(t => t.ReviewTime >= from && t.ReviewTime <= to && t.Status >= TopicStatus.Execution);
            Dictionary<int, int> topicMonthDic = new Dictionary<int, int>();
            foreach (Topic topic in topics)
            {
                topicMonthDic.Add(topic.ID, topic.ReviewTime.Value.Month);

                if (monthNumbers[topic.ReviewTime.Value.Month][0] == null)
                    monthNumbers[topic.ReviewTime.Value.Month][0] = topic.Title;
                else
                    monthNumbers[topic.ReviewTime.Value.Month][0] += (";" + topic.Title);
            }


            monthNumbers.Add(0, new object[] { null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
            foreach (Idea idea in ideas)
            {
                switch (idea.FinalAction)
                {
                    case NextAction.PRODUCT:
                        monthNumbers[topicMonthDic[idea.TopicID]][1] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][1])) + 1;
                        monthNumbers[0][1] = ((int)(monthNumbers[0][1])) + 1;
                        break;
                    case NextAction.JUSTDOIT:
                        monthNumbers[topicMonthDic[idea.TopicID]][2] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][2])) + 1;
                        monthNumbers[0][2] = ((int)(monthNumbers[0][2])) + 1;
                        break;
                    case NextAction.CPROJECT:
                        monthNumbers[topicMonthDic[idea.TopicID]][3] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][3])) + 1;
                        monthNumbers[0][3] = ((int)(monthNumbers[0][3])) + 1;
                        break;
                    case NextAction.GROUPC:
                        monthNumbers[topicMonthDic[idea.TopicID]][4] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][4])) + 1;
                        monthNumbers[0][4] = ((int)(monthNumbers[0][4])) + 1;
                        break;
                    case NextAction.TBD:
                        monthNumbers[topicMonthDic[idea.TopicID]][5] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][5])) + 1;
                        monthNumbers[0][5] = ((int)(monthNumbers[0][5])) + 1;
                        break;
                    case NextAction.MKT:
                        monthNumbers[topicMonthDic[idea.TopicID]][6] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][6])) + 1;
                        monthNumbers[0][6] = ((int)(monthNumbers[0][6])) + 1;
                        break;
                    case NextAction.NEXTROUND:
                        monthNumbers[topicMonthDic[idea.TopicID]][7] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][7])) + 1;
                        monthNumbers[0][7] = ((int)(monthNumbers[0][7])) + 1;
                        break;
                    case NextAction.OTHERBU:
                        monthNumbers[topicMonthDic[idea.TopicID]][8] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][8])) + 1;
                        monthNumbers[0][8] = ((int)(monthNumbers[0][8])) + 1;
                        break;
                }

                if (idea.FinalAward.HasValue)
                {
                    monthNumbers[topicMonthDic[idea.TopicID]][9] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][9])) + 1;
                    monthNumbers[0][9] = ((int)(monthNumbers[0][9])) + 1;
                }

                if (idea.FinalIP == true)
                {
                    monthNumbers[topicMonthDic[idea.TopicID]][10] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][10])) + 1;
                    monthNumbers[0][10] = ((int)(monthNumbers[0][10])) + 1;
                }

                monthNumbers[topicMonthDic[idea.TopicID]][11] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][11])) + 1;
                monthNumbers[0][11] = ((int)(monthNumbers[0][11])) + 1;
            }


            return monthNumbers;
        }

        public List<object[]> TeamNumberByTime(DateTime from, DateTime to)
        {
            List<Idea> ideas = new IdeaBl().SearchIdeaForStat(null, from, to);

            List<Topic> topics = new TopicBl().GetTopic();//.FindAll(t => t.ReviewTime >= from && t.ReviewTime <= to && t.Status >= TopicStatus.Execution);
            int topicCount = topics.Count;
            Dictionary<int, int> topicsIndexDic = new Dictionary<int, int>();
            for (int i = 0; i < topicCount; i++)
            {
                topicsIndexDic.Add(topics[i].ID, i+4);
            }

            List<Team> teams = new TeamBl().GetTeam(null, true, null, null);                // 所有
            List<User> users = new UserBl().GetUser(null, null, null, null, null, null);     // 所有

            Dictionary<int, Team> teamsDic = new Dictionary<int, Team>();

            Dictionary<int, object[]> teamNumbers = new Dictionary<int, object[]>();

            foreach (Team team in teams)
            {
                teamsDic.Add(team.ID, team);

                object[] data = new object[topicCount + 4];
                for (int i = 0; i <= topicCount; i++)
                {
                    data[i+3] = 0;
                }
                data[0] = team.ID;
                data[1] = team.Title;
                data[2] = team.Manager;

                teamNumbers.Add(team.ID, data);
            }
            object[] all = new object[topicCount + 4];
            for (int i = 0; i <= topicCount; i++)
            {
                all[i + 3] = 0;
            }
            all[0] = 0;
            all[1] = "";
            all[2] = "";


            Dictionary<string, int> userTeamsDic = new Dictionary<string,int>();
            foreach(User user in users)
            {
                userTeamsDic.Add(user.ItCode, user.TeamID);
            }


            foreach (Idea idea in ideas)
            {
                int userTeamID = idea.TeamID;       // 已提交时的Team为统计依据 //userTeamsDic[idea.Owner];
                int topicIndex = topicsIndexDic[idea.TopicID];

                teamNumbers[userTeamID][topicIndex] = (int)(teamNumbers[userTeamID][topicIndex]) + 1;
            }


            List<int> invalids = new List<int>();
            foreach (object[] data in teamNumbers.Values)
            {
                int total = 0;
                for (int i = 0; i < topicCount; i++)
                {
                    total += (int)data[i + 4];

                    all[i + 4] = (int)all[i + 4] + (int)data[i + 4];
                }
                data[3] = total;
                all[3] = (int)all[3] + total;

                if (total == 0 && !teamsDic[(int)data[0]].Enabled)
                    invalids.Add((int)data[0]);
            }
            foreach (int invalid in invalids)
                teamNumbers.Remove(invalid);

            teamNumbers.Add(0, all);



            List<object[]> result = new List<object[]>();
            teams.Sort((x, y) => x.Title.CompareTo(y.Title));
            foreach (Team team in teams)
            {
                if (teamNumbers.ContainsKey(team.ID))
                    result.Add(teamNumbers[team.ID]);
            }
            result.Add(teamNumbers[0]);
            result.Add(topics.ToArray());

            return result;
        }

        public List<object[]> GmoManagerNumberByTime(DateTime from, DateTime to)
        {
            List<Idea> ideas = new IdeaBl().SearchIdeaForStat(null, from, to);


            List<Team> teams = new TeamBl().GetTeam(null, true, null, null);                // 所有
            List<User> users = new UserBl().GetUser(null, null, null, null, null, null);     // 所有

            Dictionary<int, Team> teamsDic = new Dictionary<int, Team>();

            Dictionary<string, object[]> managerNumbers = new Dictionary<string, object[]>();


            foreach (Team team in teams)
            {
                teamsDic.Add(team.ID, team);

                if (!managerNumbers.ContainsKey(team.Manager))
                    managerNumbers.Add(team.Manager, new object[] { team.Manager, team.VP, 0,0,0,0,0,0,0,0,0,0,0, null });
            }


            


            Dictionary<string, int> userTeamsDic = new Dictionary<string, int>();
            foreach (User user in users)
            {
                userTeamsDic.Add(user.ItCode, user.TeamID);
            }


            foreach (Idea idea in ideas)
            {
                int userTeamID = idea.TeamID;       // 已提交时的Team为统计依据 //userTeamsDic[idea.Owner];
                string teamManager = teamsDic[userTeamID].Manager;      // Team当前的Manager


                switch (idea.FinalAction)
                {
                    case NextAction.PRODUCT:
                        managerNumbers[teamManager][2] = ((int)(managerNumbers[teamManager][2])) + 1;
                        break;
                    case NextAction.JUSTDOIT:
                        managerNumbers[teamManager][3] = ((int)(managerNumbers[teamManager][3])) + 1;
                        break;
                    case NextAction.CPROJECT:
                        managerNumbers[teamManager][4] = ((int)(managerNumbers[teamManager][4])) + 1;
                        break;
                    case NextAction.GROUPC:
                        managerNumbers[teamManager][5] = ((int)(managerNumbers[teamManager][5])) + 1;
                        break;
                    case NextAction.TBD:
                        managerNumbers[teamManager][6] = ((int)(managerNumbers[teamManager][6])) + 1;
                        break;
                    case NextAction.MKT:
                        managerNumbers[teamManager][7] = ((int)(managerNumbers[teamManager][7])) + 1;
                        break;
                    case NextAction.NEXTROUND:
                        managerNumbers[teamManager][8] = ((int)(managerNumbers[teamManager][8])) + 1;
                        break;
                    case NextAction.OTHERBU:
                        managerNumbers[teamManager][9] = ((int)(managerNumbers[teamManager][9])) + 1;
                        break;
                }

                if (idea.FinalAward.HasValue)
                {
                    managerNumbers[teamManager][10] = ((int)(managerNumbers[teamManager][10])) + 1;
                }

                if (idea.FinalIP == true)
                {
                    managerNumbers[teamManager][11] = ((int)(managerNumbers[teamManager][11])) + 1;
                }

                managerNumbers[teamManager][12] = ((int)(managerNumbers[teamManager][12])) + 1;

            }

            List<string> invalids = new List<string>();
            foreach (object[] data in managerNumbers.Values)
            {
                if ((int)data[12] == 0)
                { 
                    if (teams.FindAll(t=>t.Manager == (string)data[0]).All(t=>!t.Enabled))
                        invalids.Add((string)data[0]);
                }
            }

            foreach (string invalid in invalids)
                managerNumbers.Remove(invalid);


            // 统计vp
            Dictionary<string, int[]> vpNumbers = new Dictionary<string,int[]>();
            foreach (object[] data in managerNumbers.Values)
            {
                string vp = (string)data[1];
                int[] number = null;
                if (!vpNumbers.ContainsKey(vp)) 
                {
                    number = new int[] {0,0,0,0,0,0,0,0,0,0,0, 0};
                    vpNumbers.Add(vp, number);
                }
                else
                    number = vpNumbers[vp];

                number[0] += (int)data[2];
                number[1] += (int)data[3];
                number[2] += (int)data[4];
                number[3] += (int)data[5];
                number[4] += (int)data[6];
                number[5] += (int)data[7];
                number[6] += (int)data[8];
                number[7] += (int)data[9];
                number[8] += (int)data[10];
                number[9] += (int)data[11];
                number[10] += (int)data[12];

                number[11]++;   // manager数量

            }
            foreach (object[] data in managerNumbers.Values)
            {
                data[13] = vpNumbers[(string)data[1]];
            }


            List<object[]> result = new List<object[]>();
            result.AddRange(managerNumbers.Values);
            // 排序
            result.Sort(delegate(object[] x, object[] y) 
            {
                int s = ((string)x[1]).CompareTo((string)y[1]);
                if (s == 0)
                    s = ((string)x[0]).CompareTo((string)y[0]);

                return s;
            });


            return result;
        }

        public Dictionary<int, object[]> IPNumberByTime(DateTime from, DateTime to)
        {
            List<Idea> ideas = new IdeaBl().SearchIdeaForStat(null, from, to);



            Dictionary<int, object[]> monthNumbers = new Dictionary<int, object[]>();
            for (int i = from.Month; i <= to.Month; i++)
            {
                monthNumbers.Add(i, new object[] { null, 0, 0, 0 });
            }

            List<Topic> topics = new TopicBl().GetTopic().FindAll(t => t.ReviewTime >= from && t.ReviewTime <= to && t.Status >= TopicStatus.Execution);
            Dictionary<int, int> topicMonthDic = new Dictionary<int, int>();
            foreach (Topic topic in topics)
            {
                topicMonthDic.Add(topic.ID, topic.ReviewTime.Value.Month);

                if (monthNumbers[topic.ReviewTime.Value.Month][0] == null)
                    monthNumbers[topic.ReviewTime.Value.Month][0] = topic.Title;
                else
                    monthNumbers[topic.ReviewTime.Value.Month][0] += (";" + topic.Title);
            }


            monthNumbers.Add(0, new object[] { null, 0, 0, 0 });
            foreach (Idea idea in ideas)
            {
                switch (idea.FinalIPStatus)
                {
                    case ExecutionStatus.None:
                    case ExecutionStatus.Preparing:
                    case ExecutionStatus.OnGoing:
                        monthNumbers[topicMonthDic[idea.TopicID]][2] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][2])) + 1;
                        monthNumbers[0][2] = ((int)(monthNumbers[0][2])) + 1;
                        break;
                    case ExecutionStatus.Finished:
                        monthNumbers[topicMonthDic[idea.TopicID]][3] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][3])) + 1;
                        monthNumbers[0][3] = ((int)(monthNumbers[0][3])) + 1;
                        break;
                    case ExecutionStatus.Canceled:
                        monthNumbers[topicMonthDic[idea.TopicID]][2] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][2])) + 1;
                        monthNumbers[0][2] = ((int)(monthNumbers[0][2])) + 1;
                        break;
                }

                monthNumbers[topicMonthDic[idea.TopicID]][1] = ((int)(monthNumbers[topicMonthDic[idea.TopicID]][1])) + 1;
                monthNumbers[0][1] = ((int)(monthNumbers[0][1])) + 1;
            }


            return monthNumbers;
        }

    }
}
